#include "format.hpp"
#include "sink.hpp"

// 扩展以时间作为文件滚动切换类型的日志落地模块
//    以时间进行文件滚动，实际上是以时间段进行滚动
//    实现思想：以当前系统时间，取模时间段大小，可以得到当前时间段时第几个时间段
//              每次以当前系统时间取模，判断与当前文件的时间段是否一致，不一致代表不是同一个时间段

enum class TimeGap
{
  GAP_SECOND,
  GAP_MINUTE,
  GAP_HOUR,
  GAP_DAY
};
class RollByTimeSink : public qywlog::LogSink
{
  public:
  RollByTimeSink(const std::string &basename, TimeGap gap_type)
    :_basename(basename)
  {
    switch(gap_type)
    {
      case TimeGap::GAP_SECOND:
        _gap_size = 1; break;
      case TimeGap::GAP_MINUTE:
        _gap_size = 60; break;
      case TimeGap::GAP_HOUR:
        _gap_size = 3600; break;
      case TimeGap::GAP_DAY:
        _gap_size = 3600*24; break;
    }
    _cur_gap = _gap_size==1 
      ? qywlog::util::Date::now() 
      : qywlog::util::Date::now() % _gap_size;//获取当前文件创建时，是第几个时间段
    std::string pathname = createNewFile();
    qywlog::util::File::createDirectory(qywlog::util::File::path(pathname));
    _ofs.open(pathname,std::ios::binary | std::ios::app);
    assert(_ofs.is_open());
  }
  void log(const char *data, size_t len) override
  {
    time_t cur = qywlog::util::Date::now();// 获取当前的时间码
    if((cur % _gap_size) != _cur_gap)
    {
      _ofs.close();
      std::string pathname = createNewFile();
      _ofs.open(pathname,std::ios::binary | std::ios::app);
      assert(_ofs.is_open());
     _cur_gap = _gap_size==1 
      ? qywlog::util::Date::now() 
      : qywlog::util::Date::now() % _gap_size;//获取当前文件创建时，是第几个时间段
    }
    _ofs.write(data, len);
    assert(_ofs.good());
  }
  private:
  std::string createNewFile()
  {
    time_t t = qywlog::util::Date::now();
    struct tm lt;
    localtime_r(&t, &lt);
    std::stringstream pathname;
    pathname << _basename;
    pathname << lt.tm_year + 1900;
    pathname << lt.tm_mon + 1;
    pathname << lt.tm_mday;
    pathname << lt.tm_hour;
    pathname << lt.tm_min;
    pathname << lt.tm_sec;
    pathname << ".log";
   return pathname.str(); 
  }
  private:
  std::string _basename;
  std::ofstream _ofs;
  size_t _gap_size;
  size_t _cur_gap;
};

int main()
{
  qywlog::LogMsg msg(qywlog::LogLevel::value::INFO,53,"main.c","root","格式化功能测试..."); 
  qywlog::Formatter fmt;
  std::string str = fmt.format(msg);
  //qywlog::LogSink::ptr stdout_lsp = qywlog::SinkFactory::create<qywlog::StdoutSink>();
  //qywlog::LogSink::ptr file_lsp = qywlog::SinkFactory::create<qywlog::FileSink>("./logfile/test.log");
  //qywlog::LogSink::ptr roll_lsp = qywlog::SinkFactory::create<qywlog::RollBySizeSink>("./logfile/roll-",1024*1024);
  qywlog::LogSink::ptr time_lsp = qywlog::SinkFactory::create<RollByTimeSink>("./logfile/roll-",TimeGap::GAP_SECOND);
  //stdout_lsp->log(str.c_str(),str.size());
  //file_lsp->log(str.c_str(),str.size());
  //size_t cursize = 0;
  //size_t count = 0;
  //while(cursize < 1024*1024*10)
  //{
    //std::string tmp = str + std::to_string(count++);
    //roll_lsp->log(tmp.c_str(),tmp.size());
    //cursize += tmp.size();
  //}
  time_t old = qywlog::util::Date::now();
  while(qywlog::util::Date::now() < old+5)
  {
    time_lsp->log(str.c_str(),str.size());
  }

  return 0;
}
